#ifndef LIST_H
#define LIST_H

#include <sstream>
#include <iostream>
#include <tr1/unordered_map>
#include <set>
#include <vector>
#include <iterator>
#include <tuple>
using namespace std;
using namespace tr1;


template<typename T, int size>
int GetArrLength(T(&)[size]){return size;}

class list {						//declaration of a new class

public :
	struct el {
		public:
			list::list * parent;
			int element;
			int epsilon;

			el(int element) {
				this->element = element;
				epsilon = 0;
			}

			el (int element, int epsilon) {
				this->element = element;
				this->epsilon = epsilon;
			}

			~el() {};

			void assign(list * _parent) {
				this->parent = _parent;
			}

			bool operator<(const el& other) const {
				return element < other.element;
			}

			string to_string() {
				stringstream out;
				out << this->element << ":" << this->epsilon;
				return out.str();
			}
		};


public:
	set<list::el*> elements;
	vector<list::list *> remove(el * el);//A function used to create a new element in the list with a return type element*
	void add(list::el * el);//A function used to search for elements in the list with a return type element*
	void set_prev(list * prev);
	void set_next(list * next);
	tuple<list*,list*, el*> replace_min();
	set<el*> get_elements();
	bool isEmpty();


	list(list * prev, list * next);
	list(list * prev, list * next, int count);
	~list();
	string to_string();

	int count;
	list * prev;//a pointer to the element structure called FirstEl. It will hold the address of the first element in the list
	list * next;//a pointer to the element structure called LastEl. It will hold the address of the last element in the list

	bool operator==(const list& other) const {
		return count == other.count;
	}
};


typedef list::el EL;
typedef list::list BUCKET;
typedef vector<list::list*> VECTOR_LIST;
typedef tuple<list*, list*, EL*> TUPLE_LIST_EL;
#endif
